package com.bzsg.simpleMediaPlayer.extend

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext

inline fun ViewModel.requestMain(
    errCode: Int = -1,
    errMsg: String = "",
    report: Boolean = false,
    noinline block: suspend CoroutineScope.() -> Unit,
) {
    viewModelScope.launch(GlobalCoroutineExceptionHandler(errCode, errMsg, report)) {
        block.invoke(this)
    }
}

inline fun ViewModel.requestIO(
    errCode: Int = -1,
    errMsg: String = "",
    report: Boolean = false,
    noinline block: suspend CoroutineScope.() -> Unit,
) {
    viewModelScope.launch(Dispatchers.IO + GlobalCoroutineExceptionHandler(errCode, errMsg, report)) {
        block.invoke(this)
    }
}

inline fun ViewModel.delayMain(
    errCode: Int = -1,
    errMsg: String = "",
    report: Boolean = false,
    delayTime: Long,
    noinline block: suspend CoroutineScope.() -> Unit,
) {
    viewModelScope.launch(GlobalCoroutineExceptionHandler(errCode, errMsg, report)) {
        withContext(Dispatchers.IO) {
            delay(delayTime)
        }
        block.invoke(this)
    }
}

/**
 * @param errCode 错误码
 * @param errMsg 简要错误信息
 * @param report 是否需要上报
 */
class GlobalCoroutineExceptionHandler(private val errCode: Int, private val errMsg: String = "", private val report: Boolean = false) :
    CoroutineExceptionHandler {
    override val key: CoroutineContext.Key<*>
        get() = CoroutineExceptionHandler

    override fun handleException(
        context: CoroutineContext,
        exception: Throwable,
    ) {
        val msg = exception.stackTraceToString()
        Log.e("$errCode", "GlobalCoroutineExceptionHandler:$msg")
    }
}
